#include <stdio.h> // 包含标准输入输出库
#include <stdlib.h> // 包含标准库函数
#include <string.h> // 包含字符串操作函数
#include <errno.h> // 包含错误号定义
#include <unistd.h> // 包含UNIX标准函数定义
#include <sys/types.h> // 包含数据类型定义
#include <sys/socket.h> // 包含套接字接口函数定义
#include <netinet/in.h> // 包含网络接口函数定义
#include <arpa/inet.h> // 包含网络地址转换函数定义
#include <sys/epoll.h> // 包含epoll的函数定义
#include <sqlite3.h> // SQLite的头文件
#include <getopt.h> // 命令行选项解析

#define BACKLOG 13 // 定义监听队列的长度
#define MAX_EVENTS 10 // 定义epoll监听的最大事件数
#define BUF_SIZE 1024 // 定义缓冲区大小

void save_to_database(const char *data) 
{
    sqlite3 *db;
    char *errMsg = 0;
    int rc;

    // 打开数据库
    rc = sqlite3_open("temperature.db", &db);
    if (rc != SQLITE_OK) 
    {
        fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return;
    }

    // 创建表（如果不存在）
    const char *create_table_sql = "CREATE TABLE IF NOT EXISTS guhe ("
                                    "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                                    "data TEXT NOT NULL);";
    rc = sqlite3_exec(db, create_table_sql, 0, 0, &errMsg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL错误: %s\n", errMsg);
        sqlite3_free(errMsg);
    }

    // 定义SQL查询
    char query[256];
    snprintf(query, sizeof(query), "INSERT INTO guhe (data) VALUES ('%s');", data);

    // 执行SQL语句
    rc = sqlite3_exec(db, query, 0, 0, &errMsg);
    if (rc != SQLITE_OK) 
    {
        fprintf(stderr, "SQL错误: %s\n", errMsg);
        sqlite3_free(errMsg);
    }

    // 关闭数据库
    sqlite3_close(db);
}

int main(int argc, char **argv) 
{
    int listen_fd, epoll_fd, port = 2222; // 默认端口号
    struct sockaddr_in server_addr;
    struct epoll_event ev, events[MAX_EVENTS];

    // 命令行参数解析
    int opt;
    while ((opt = getopt(argc, argv, "p:")) != -1) {
        switch (opt) {
            case 'p':
                port = atoi(optarg); // 获取端口号
                break;
            default:
                fprintf(stderr, "用法: %s -p <端口号>\n", argv[0]);
                exit(EXIT_FAILURE);
        }
    }

    // 创建套接字
    listen_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (listen_fd == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }
    printf("Socket created: %d\n", listen_fd);

    // 设置服务器地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(port);

    // 绑定套接字
    if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) 
    {
        perror("bind");
        close(listen_fd);
        exit(EXIT_FAILURE);
    }
    printf("Socket bound to port %d\n", port);

    // 监听套接字
    if (listen(listen_fd, BACKLOG) == -1) 
    {
        perror("listen");
        close(listen_fd);
        exit(EXIT_FAILURE);
    }
    printf("Listening on socket: %d\n", listen_fd);

    // 创建epoll实例
    epoll_fd = epoll_create1(0);
    if (epoll_fd == -1) 
    {
        perror("epoll_create1");
        close(listen_fd);
        exit(EXIT_FAILURE);
    }
    printf("Epoll instance created: %d\n", epoll_fd);

    // 设置事件
    ev.events = EPOLLIN;
    ev.data.fd = listen_fd;
    printf("Adding listen_fd to epoll: %d\n", listen_fd);

    // 添加事件到epoll实例
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) == -1) 
    {
        perror("epoll_ctl: listen_fd");
        close(listen_fd);
        close(epoll_fd);
        exit(EXIT_FAILURE);
    }
    printf("listen_fd added to epoll\n");

    // 事件循环
    while (1)
    {
        int n = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        if (n == -1)
        {
            perror("epoll_wait");
            break;
        }

        for (int i = 0; i < n; i++) 
        {
            if (events[i].data.fd == listen_fd)
            {
                // 接受新的连接
                int conn_fd = accept(listen_fd, NULL, NULL);
                if (conn_fd == -1) {
                    perror("accept");
                    continue;
                }
                printf("Accepted connection: %d\n", conn_fd);

                // 设置新连接的事件
                ev.events = EPOLLIN;
                ev.data.fd = conn_fd;

                // 添加新连接到epoll实例
                if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_fd, &ev) == -1) 
                {
                    perror("epoll_ctl: conn_fd");
                    close(conn_fd);
                } else 
                {
                    printf("conn_fd added to epoll: %d\n", conn_fd);
                }
            }
            else 
            {
                // 处理数据接收
                char buffer[BUF_SIZE];
                ssize_t bytes_received = recv(events[i].data.fd, buffer, sizeof(buffer) - 1, 0);
                if (bytes_received <= 0) 
                {
                    // 关闭连接
                    close(events[i].data.fd);
                    continue;
                }

                // 确保字符串以 null 结束
                buffer[bytes_received] = '\0';
                printf("Data ready on fd:\n %d\n", events[i].data.fd);
                printf("Received data is:\n %s\n", buffer);

                // 保存数据到数据库
                save_to_database(buffer);
                printf("保存到数据库完成\n");          
            }
        }
    }

    // 关闭套接字和epoll实例
    close(listen_fd);
    close(epoll_fd);
    return 0;
}
